
import netifaces
import subprocess
import os
import shutil
from change_ip import change_ip,dhcp_ip
from setting import logger


def get_network_info(interface="eth0"):
    """
    >>> get_network_info("eth0")
    >>> {'ip_address': '192.168.88.200', 'netmask': '255.255.255.0', 'gateway': '192.168.88.1'}
    """
    info = {}
    addrs = netifaces.ifaddresses(interface)
    
    if netifaces.AF_INET in addrs:
        info['ip_address'] = addrs[netifaces.AF_INET][0]['addr']
        info['netmask'] = addrs[netifaces.AF_INET][0]['netmask']
        info['gateway'] = netifaces.gateways()[netifaces.AF_INET][0][0]
        # info['broadcast'] = addrs[netifaces.AF_INET][0]['broadcast']
    else:
        
        return None
    
    return info

def generate_ip_list(host, net_mask):
    # 将IP地址和子网掩码转换为十进制形弄1�7
    host_dec = ip_to_decimal(host)
    net_mask_dec = ip_to_decimal(net_mask)

    # 计算网络地址
    network_address = host_dec & net_mask_dec

    # 计算广播地址
    broadcast_address = network_address | (~net_mask_dec & 0xFFFFFFFF)

    ip_list = []
    # 生成扢�有IP地址(排除网络地址和广播地坢�)
    for ip in range(network_address+1, broadcast_address):
        ip_list.append(decimal_to_ip(ip))
    
    return ip_list

def ip_to_decimal(ip):
    # 将IP地址转换为十进制形式
    octets = ip.split('.')
    decimal = 0
    for i in range(4):
        decimal += int(octets[i]) << (24 - (8 * i))
    return decimal

def decimal_to_ip(decimal):
    # 将十进制形式的IP地址转换为字符串形式
    octets = []
    for i in range(4):
        octets.append(str((decimal >> (24 - (8 * i))) & 255))
    return '.'.join(octets)

network_info = {
    'net_mask': '255.0.0.0',
    'gateway': '192.168.88.1'
}

def generate_ip_by_index(host, net_mask, index):
    # 将IP地址和子网掩码转换为十进制形弄1�7
    host_dec = ip_to_decimal(host)
    net_mask_dec = ip_to_decimal(net_mask)

    # 计算网络地址
    network_address = host_dec & net_mask_dec
    
    # 根据索引计算对应位置的IP地址
    ip_dec = network_address + index

    # 将十进制形式的IP地址转换为字符串形式
    ip = decimal_to_ip(ip_dec)
    
    return ip


def check_ip_availability(ip):
    '''测试IP是否被占用'''
    command = ['ping', '-c', '1', '-W', '1', ip]  # Linux
    # command = ['ping', '-n', '1', '-w', '1000', ip] # Windows

    try:
        result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
        if result.returncode == 0:
            return True  # IP地址可达
        else:
            return False  # IP地址不可达
    except subprocess.CalledProcessError:
        return False
    

def get_ip_count(netmask="255.255.255.0") -> int:
    '''获取netmask有效ip数量
    >>> get_ip_count("255.255.255.0")
    >>> 254
    '''
    # 将掩码转换为二进制字符串
    binary_netmask = ''.join([bin(int(x)).lstrip('0b').zfill(8) for x in netmask.split('.')])

    # 计算主机位的数量
    host_bits = binary_netmask.count('0')

    # 计算IP数量（排除了网络地址和广播地址）
    ip_count = 2 ** host_bits - 2

    return ip_count

def special_traversal(start, end):
    if start > end:
        return

    mid = (start + end) // 2
    print(mid)

    special_traversal(start, mid - 1)
    special_traversal(mid + 1, end)

def check_ip_end(ip):
    '''检查ip结尾
    >>> check_ip_end('192.168.88.0')
    >>> True
    >>> check_ip_end('192.168.88.255')
    >>> True
    >>> check_ip_end('192.168.88.1')
    >>> False
    '''
    tail = int(ip.split(".")[-1])
    if tail == 0 or tail == 255:
        return True
    return False


def get_enbale_ip(gateway, netmask):
    '''获取主站IP'''
    for i in range(get_ip_count(netmask)):

        ip = generate_ip_by_index(gateway, netmask, i)

        if check_ip_end(ip): # 过滤结尾255和0

            continue

        if not check_ip_availability(ip): # ip 没有被占用时

            return ip

    return None # "当前网段没有空闲的地址"

def check_now_ip(gateway) -> bool :
    '''检测ip是否需要更改'''

    file_path = "ip_data"

    if not os.path.exists(file_path):

        return True
    
    if not check_ip_availability(gateway):

        shutil.os.remove(file_path)

        dhcp_ip()

        return False
    
    return False

def auto_ip():

    if not check_now_ip():
        return

    # 获取网络信息 {'ip_address': '192.168.88.200', 'netmask': '255.255.255.0', 'gateway': '192.168.88.1'}
    network_info = get_network_info('eth0')

    if network_info is None:

        logger.info("本机没有被分配IP地址")

        return

    master_ip = get_enbale_ip(network_info["gateway"], network_info["netmask"])

    logger.info(f"主站ip将设定为：{master_ip}")
    change_ip(ip_address=master_ip, netmask=network_info["netmask"], gateway=network_info["gateway"])



if __name__ == "__main__":

    # # 获取网络信息
    # network_info = get_network_info('eth0')  # 射1�7 'eth0' 替换为您要查询的网络接口名称
    # print(network_info)

    # network_info = {
    #     'net_mask': '255.255.0.0',
    #     'gateway': '192.168.88.1'
    # }

    # # 假设要计算索引为10的IP地址
    # ip_index = 256

    # ip = generate_ip_by_index(network_info['gateway'], network_info['net_mask'], ip_index)

    # print(ip)

    # print(get_ip_count("255.255.0.0"))

    ip = auto_ip()




    
